#include "common.h"
#include <Arduino.h>
#include <NimBLEDevice.h>

#ifndef _BleServerConnector_H
#define _BleServerConnector_H

// BLE_HID设备
// HID服务UUID
const static BLEUUID BLE_SERVER_SERVICE_UUID_HID((uint16_t)0x1812);
// HID特征UUID     :设备信息(Hid Information)
const static BLEUUID BLE_SERVER_CHAR_UUID_UUID_2A4A((uint16_t)0x2a4a);
// HID特征UUID     :报表格式(Report Map)——说明报表的格式
const static BLEUUID BLE_SERVER_CHAR_UUID_UUID_2A4B((uint16_t)0x2a4b);
// HID特征UUID(W)  :(Hid Control Point)——向设备告知主机的状态
const static BLEUUID BLE_SERVER_CHAR_UUID_UUID_2A4C((uint16_t)0x2a4c);
// HID特征UUID(R/W):(Report)数据报表——设备与主机交互数据
const static BLEUUID BLE_SERVER_CHAR_UUID_UUID_2A4D((uint16_t)0x2a4d);
// HID特征UUID(W)  :协议模式(Protocol Mode)
const static BLEUUID BLE_SERVER_CHAR_UUID_UUID_2A4E((uint16_t)0x2a4e);

class BleServerConnector;

class BleServerConnectorCallbacks {
public:
    virtual void ble_onConnect(BleServerConnector *pBleServerConnector, BLERemoteService *pRemoteService, bool &flag) { ; }
    virtual void ble_onDisconnect(BleServerConnector *pBleServerConnector) { ; }
    virtual void ble_bindReadReportCharacteristic(BleServerConnector *pBleServerConnector, BLERemoteCharacteristic *_pReadReportCharacteristic) { ; }
};

// BLE HID
class BleServerConnector : public NimBLEClientCallbacks {
public:
    char _name[33] = {0};    // 设备名称
    char _address[18] = {0}; // 地址
    uint8_t _addressType = 0;
    int _type = 0;          //  (0:未知  1：键盘 2:鼠标)
    int _keyboard_mode = 0; // 0: 美式键盘; 1:日式键盘
    int _status = 0;        // 连接状态    (-1:连接失败 0:未连接 1:已连接 2：已配对 3:已识别(HID))
    int _cntFail = 0;       // 尝试失败次数
    int _ConnTimeout = 99;  // 连接保持的最长无通信时间

private:
    bool _isEmpty = true; // 表示是否已占用数组位置
    bool _fixed = false;  // 表示是否固定（不可删除）

    BleServerConnectorCallbacks *_pCallbacks = nullptr; // 事件通知对象

    typedef void (*setOnRecvData_t)(BleServerConnector *_pConnect, uint8_t *dataBuf, int nLen);
    void (*onRecvData)(BleServerConnector *_pConnect, uint8_t *dataBuf, int nLen);

    // 这些在连接后才设值
    BLEClient *_BLEClient = nullptr; // 客户端，用于连接BLE Server
    BLERemoteCharacteristic *_pReadReportCharacteristic = nullptr;
    BLERemoteCharacteristic *_pWriteReportCharacteristic = nullptr;

public:
    bool isEmpty();
    void destory();
    void clear();
    void connectToServer();
    void recvData(uint8_t *dataBuf, int nLen, bool isNotify);
    std::string readValue();

    // 控制键盘灯
    void setLED(uint8_t flags);

    void setBleServerConnectorCallbacks(BleServerConnectorCallbacks *pCallbacks);
    void setOnRecvData(setOnRecvData_t cb);

    // -----------------------------------------------
    // BLEClientCallbacks
    // -----------------------------------------------
    // 回调函数：连上服务端
    void onConnect(NimBLEClient *pclient);
    // 回调函数：断开服务端
    void onDisconnect(NimBLEClient *pClient, int reason);
    void onPassKeyEntry(NimBLEConnInfo &connInfo);
    void onConfirmPasskey(NimBLEConnInfo &connInfo, uint32_t pass_key);
    void onAuthenticationComplete(NimBLEConnInfo &connInfo);

    friend void handleDevices();
    friend class BleManager;
};

#endif
